package com.manthano.util.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * @author DELL
 */
public class FileUtil
{
	/**
	 * @param text
	 * @param replace
	 * @return String
	 */
	public static String replaceInvalidFileNameCharacters(String text, String replace)
	{

		return text.replaceAll(":|\\*|\\?|\\\"|<|>|\\||/|\\\\", replace);
	}

	/**
	 * @param classPathFile
	 * @return String Buffer
	 * @throws IOException
	 */
	public static StringBuffer getFileAsStringBuffer(String classPathFile) throws IOException
	{
		InputStream inputStream = null;

		BufferedReader bufferedReader = null;
		StringBuffer stringBuffer = null;
		try
		{
			inputStream = FileUtil.class.getClassLoader().getResourceAsStream(classPathFile);
			bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			stringBuffer = new StringBuffer();
			String line = null;
			while ((line = bufferedReader.readLine()) != null)
			{
				stringBuffer.append(line + "\n");
			}
		}
		finally
		{
			if (bufferedReader != null)
			{
				bufferedReader.close();
				bufferedReader = null;
			}
			if (inputStream != null)
			{
				inputStream.close();
			}
		}
		return stringBuffer;
	}

	/**
	 * @param content
	 * @param filePath
	 * @throws IOException
	 */
	public static void writeStringToFile(String content, String filePath) throws IOException
	{
		BufferedWriter bufferedWriter = null;
		FileChannel fileChannel = null;
		FileOutputStream fileOutputStream = null;
		try
		{
			fileOutputStream = new FileOutputStream(filePath);
			fileChannel = fileOutputStream.getChannel();
			bufferedWriter = new BufferedWriter(Channels.newWriter(fileChannel, "UTF-8"));
			bufferedWriter.write(content);
		}
		finally
		{
			try
			{
				if (fileOutputStream != null)
				{
					fileOutputStream.close();
					fileOutputStream = null;
				}
			}
			catch (IOException e)
			{}
			try
			{
				if (bufferedWriter != null)
				{
					bufferedWriter.close();
					bufferedWriter = null;
				}
			}
			catch (IOException e)
			{}
			try
			{
				if (fileChannel != null)
				{
					fileChannel.close();
					fileChannel = null;
				}
			}
			catch (IOException e)
			{}
		}
	}

	/**
	 * @param sourcePath
	 *            e.g C:\\Vaibhav\\cXML
	 * @param destinationPath
	 * @throws IOException
	 */
	public static void zipDirectory(String sourcePath, String destinationPath) throws IOException
	{
		sourcePath = sourcePath.replace('\\', '/');
		File source = new File(sourcePath);
		ZipOutputStream zipOutputStream = null;
		try
		{
			File destination = new File(destinationPath);
			if (!destination.exists())
			{
				new File(destination.getParent()).mkdirs();
			}
			zipOutputStream = new ZipOutputStream(new FileOutputStream(destination));
			if (source.isDirectory())
			{
				for (File inputFile : source.listFiles())
				{
					if (inputFile.isFile())
					{
						processFile(source, inputFile, zipOutputStream);
					}

					if (inputFile.isDirectory())
					{
						processDirectory(source, inputFile, zipOutputStream);
					}
				}
			}
			zipOutputStream.close();
		}
		finally
		{
			if (zipOutputStream != null)
			{
				zipOutputStream.close();
				zipOutputStream = null;
			}
		}
	}

	/**
	 * @param source
	 * @param list
	 * @param zipOutputStream
	 * @throws IOException
	 */
	private static void processDirectory(File source, File directory, ZipOutputStream zipOutputStream)
			throws IOException
	{

		String pathStructure = directory.getAbsolutePath().replace(source.getPath(), "").substring(1)
				.replace("\\", "/")
				+ "/";
		ZipEntry zipEntry = new ZipEntry(pathStructure);
		zipOutputStream.putNextEntry(zipEntry);
		for (File file : directory.listFiles())
		{
			if (file.isDirectory())
			{
				processDirectory(source, file, zipOutputStream);
			}
			else if (file.isFile())
			{
				processFile(source, file, zipOutputStream);
			}
		}
		zipOutputStream.closeEntry();
	}

	/**
	 * @param source
	 * @param file
	 * @param zipOutputStream
	 * @throws IOException
	 * @throws IOException
	 */
	private static void processFile(File source, File file, ZipOutputStream zipOutputStream) throws IOException
	{
		String originalFilePath = file.getAbsolutePath().replace(source.getPath(), "").trim().replace("\\", "/");
		String structure = null;
		structure = originalFilePath.replace(file.getName(), "");

		InputStream fileInputStream = null;
		try
		{
			fileInputStream = new FileInputStream(file);
			byte[] buffer = new byte[1024];
			ZipEntry zipEntry = new ZipEntry(structure.substring(1) + file.getName());
			zipOutputStream.putNextEntry(zipEntry);
			int length = 0;

			while ((length = fileInputStream.read(buffer)) != -1)
			{
				zipOutputStream.write(buffer, 0, length);
			}
			fileInputStream.close();
		}
		finally
		{
			if (fileInputStream != null)
			{
				fileInputStream.close();
				fileInputStream = null;
			}
			zipOutputStream.closeEntry();
		}
	}

	/**
	 * @param sourcePath
	 *            e.g C:\\Vaibhav\\cXML.Zip
	 * @param destinationPath
	 *            C:\\test\\
	 * @throws IOException
	 */
	public static void unZipDirectory(String sourcePath, String destinationPath) throws IOException
	{
		BufferedInputStream fileInputStream = null;
		BufferedOutputStream fileOutputStream = null;
		sourcePath = sourcePath.replace('\\', '/');
		File file = null;
		try
		{
			ZipFile zipFile = new ZipFile(sourcePath);
			Enumeration<? extends ZipEntry> entries = zipFile.entries();
			while (entries.hasMoreElements())
			{
				ZipEntry unzipEntry = entries.nextElement();
				String currentUnzipEntry = unzipEntry.getName();
				if (!unzipEntry.isDirectory())
				{
					file = new File(destinationPath + "/" + currentUnzipEntry);
					if (!file.exists())
					{
						new File(file.getParent()).mkdirs();
					}
					fileInputStream = new BufferedInputStream(zipFile.getInputStream(unzipEntry));
					fileOutputStream = new BufferedOutputStream(new FileOutputStream(destinationPath + "/"
							+ currentUnzipEntry));

					int i = 0;
					while ((i = fileInputStream.read()) != -1)
					{
						fileOutputStream.write(i);
					}
					fileInputStream.close();
					fileOutputStream.close();
				}
			}
			zipFile.close();
		}
		finally
		{
			if (fileInputStream != null)
			{
				fileInputStream.close();
				fileInputStream = null;
			}
			if (fileOutputStream != null)
			{
				fileOutputStream.close();
				fileOutputStream = null;
			}
		}
	}
}
